#include <windows.h>
#pragma comment(lib, "gdi32.lib")

enum ZBID {
	ZBID_DEFAULT = 0,
	ZBID_DESKTOP = 1,
	ZBID_UIACCESS = 2,
	ZBID_IMMERSIVE_IHM = 3,
	ZBID_IMMERSIVE_NOTIFICATION = 4,
	ZBID_IMMERSIVE_APPCHROME = 5,
	ZBID_IMMERSIVE_MOGO = 6,
	ZBID_IMMERSIVE_EDGY = 7,
	ZBID_IMMERSIVE_INACTIVEMOBODY = 8,
	ZBID_IMMERSIVE_INACTIVEDOCK = 9,
	ZBID_IMMERSIVE_ACTIVEMOBODY = 10,
	ZBID_IMMERSIVE_ACTIVEDOCK = 11,
	ZBID_IMMERSIVE_BACKGROUND = 12,
	ZBID_IMMERSIVE_SEARCH = 13,
	ZBID_GENUINE_WINDOWS = 14,
	ZBID_IMMERSIVE_RESTRICTED = 15,
	ZBID_SYSTEM_TOOLS = 16,
	ZBID_LOCK = 17,
	ZBID_ABOVELOCK_UX = 18,
};

LRESULT CALLBACK TrashParentWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
	switch (message) {
    	case WM_CREATE:
    		break;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		break;
    	case WM_WINDOWPOSCHANGING:
    		return 0;
    	case WM_CLOSE:
    		HANDLE myself;
    		myself = OpenProcess(PROCESS_ALL_ACCESS, false, GetCurrentProcessId());
    		TerminateProcess(myself, 0);
    		return true;
    	default:
    		break;
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
}

HWND hwnd = NULL;
typedef HWND(WINAPI* CreateWindowInBand)(_In_ DWORD dwExStyle, _In_opt_ ATOM atom, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam, DWORD band);

void CreateWin(HMODULE hModule, UINT zbid, const wchar_t* title, const wchar_t* classname) {
	MessageBox(NULL, TEXT("InjectedDLL"), TEXT("InjectedDLL"), MB_OK);
	{
		HINSTANCE hInstance = hModule;
		WNDCLASSEXW wndParentClass = {};
		wndParentClass.cbSize = sizeof(WNDCLASSEXW);
		wndParentClass.cbClsExtra = 0;
		wndParentClass.hIcon = NULL;
		wndParentClass.lpszMenuName = NULL;
		wndParentClass.hIconSm = NULL;
		wndParentClass.lpfnWndProc = TrashParentWndProc;
		wndParentClass.hInstance = hInstance;
		wndParentClass.style = CS_HREDRAW | CS_VREDRAW;
		wndParentClass.hCursor = LoadCursor(0, IDC_ARROW);
		wndParentClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
		wndParentClass.lpszClassName = classname;

		auto res = RegisterClassExW(&wndParentClass);

		const auto hpath = LoadLibraryW(L"user32.dll");
		const auto pCreateWindowInBand = CreateWindowInBand(GetProcAddress(hpath, "CreateWindowInBand"));

		auto hwndParent = pCreateWindowInBand(WS_EX_TOPMOST,
			res,
			title,
			WS_OVERLAPPEDWINDOW,
			CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
			NULL,
			NULL,
			wndParentClass.hInstance,
			LPVOID(res),
			zbid
       );
		ShowWindow(hwndParent, SW_SHOW);
		UpdateWindow(hwndParent);

		if (hwndParent != nullptr)
			hwnd = hwndParent;
	}
}

DWORD WINAPI Thrd(LPVOID lpParam) {
	CreateWin(NULL, ZBID_ABOVELOCK_UX, L"Created by CreateWindowInBand Function!!", L"cwinband");

	MSG msg;
	while (GetMessageW(&msg, nullptr, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessageW(&msg);
	}
}

// build: g++.exe -o cwinband.dll cwinband.dll.cpp -shared -static -lgdi32 -mwindows -municode
// inject tool: OpenArk.exe
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		CreateThread(nullptr, 0, Thrd, hModule, NULL, NULL);
	break;
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}

	return TRUE;
}
